home *** CD-ROM | disk | FTP | other *** search
/ Komputer for Alle 1999 #5 / 1999 CD 5 (black).iso / Delphi3 / install / data.z / DDEML.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1997-08-04  |  15.8 KB  |  499 lines

  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {       Delphi Runtime Library                          }
  5. {       Windows 32bit API Interface Unit                }
  6. {                                                       }
  7. {       Copyright (c) 1992,97 Borland International     }
  8. {                                                       }
  9. {*******************************************************}
  10.  
  11. unit Ddeml;
  12.  
  13. {$WEAKPACKAGEUNIT}
  14.  
  15. interface
  16.  
  17. uses Windows;
  18.  
  19. type
  20.   HConvList = Longint;
  21.   HConv = Longint;
  22.   HSz = Longint;
  23.   HDDEData = Longint;
  24.  
  25. type
  26.   { the following structure is for use with xtyp_WildConnect processing. }
  27.   PHSZPair = ^THSZPair;
  28.   THSZPair = record
  29.     hszSvc: HSZ;
  30.     hszTopic: HSZ;
  31.   end;
  32.  
  33.   { The following structure is used by DdeConnect() and DdeConnectList()
  34.     and by xtyp_Connect and xtyp_WildConnect callbacks. }
  35.  
  36.   PConvContext = ^TConvContext;
  37.   TConvContext = record
  38.     cb: UINT;            { set to sizeof(ConvCOnTEXT) }
  39.     wFlags: UINT;        { none currently defined. }
  40.     wCountryID: UINT;    { country code for topic/item strings used. }
  41.     iCodePage: Integer;  { codepage used for topic/item strings. }
  42.     dwLangID: DWORD;     { language ID for topic/item strings. }
  43.     dwSecurity: DWORD;   { Private security code. }
  44.     qos: TSecurityQualityOfService;  { used to support client impersonation }
  45.   end;
  46.  
  47. { The following structure is used by DdeQueryConvInfo(): }
  48.  
  49.   PConvInfo = ^TConvInfo;
  50.   TConvInfo = record
  51.     cb: DWORD;            { sizeof(CONVINFO)  }
  52.     hUser: DWORD;         { user specified field  }
  53.     hConvPartner: HConv;    { hConv on other end or 0 if non-ddemgr partner  }
  54.     hszSvcPartner: HSz;     { app name of partner if obtainable  }
  55.     hszServiceReq: HSz;     { AppName requested for connection  }
  56.     hszTopic: HSz;          { Topic name for conversation  }
  57.     hszItem: HSz;           { transaction item name or NULL if quiescent  }
  58.     wFmt: UINT;             { transaction format or NULL if quiescent  }
  59.     wType: UINT;            { XTYP_ for current transaction  }
  60.     wStatus: UINT;          { ST_ constant for current conversation  }
  61.     wConvst: UINT;          { XST_ constant for current transaction  }
  62.     wLastError: UINT;       { last transaction error.  }
  63.     hConvList: HConvList;   { parent hConvList if this conversation is in a list }
  64.     ConvCtxt: TConvContext; { conversation context }
  65.     hwnd: HWND;             { window handle for this conversation }
  66.     hwndPartner: HWND;      { partner window handle for this conversation }
  67.   end;
  68.  
  69. const
  70.   { conversation states (usState) }
  71.  
  72.   XST_NULL = 0;                 { quiescent states }
  73.   XST_INCOMPLETE = 1;
  74.   XST_CONNECTED = 2;
  75.   XST_INIT1 = 3;                { mid-initiation states }
  76.   XST_INIT2 = 4;
  77.   XST_REQSENT = 5;              { active conversation states }
  78.   XST_DATARCVD = 6;
  79.   XST_POKESENT = 7;
  80.   XST_POKEACKRCVD = 8;
  81.   XST_EXECSENT = 9;
  82.   XST_EXECACKRCVD = 10;
  83.   XST_ADVSENT = 11;
  84.   XST_UNADVSENT = 12;
  85.   XST_ADVACKRCVD = 13;
  86.   XST_UNADVACKRCVD = 14;
  87.   XST_ADVDATASENT = 15;
  88.   XST_ADVDATAACKRCVD = 16;
  89.  
  90.   { used in LOWORD(dwData1) of XTYP_ADVREQ callbacks... }
  91.  
  92.   CADV_LATEACK = $FFFF;
  93.  
  94.   { conversation status bits (fsStatus) }
  95.  
  96.   ST_CONNECTED = $0001;
  97.   ST_ADVISE = $0002;
  98.   ST_ISLOCAL = $0004;
  99.   ST_BLOCKED = $0008;
  100.   ST_CLIENT = $0010;
  101.   ST_TERMINATED = $0020;
  102.   ST_INLIST = $0040;
  103.   ST_BLOCKNEXT = $0080;
  104.   ST_ISSELF = $0100;
  105.  
  106.   { DDE constants for wStatus field }
  107.  
  108.   DDE_FACK = $8000;
  109.   DDE_FBUSY = $4000;
  110.   DDE_FDEFERUPD = $4000;
  111.   DDE_FACKREQ = $8000;
  112.   DDE_FRELEASE = $2000;
  113.   DDE_FREQUESTED = $1000;
  114.   DDE_FAPPSTATUS = $00ff;
  115.   DDE_FNOTPROCESSED = $0000;
  116.  
  117.   DDE_FACKRESERVED = $3ff0;
  118.   DDE_FADVRESERVED = $3fff;
  119.   DDE_FDATRESERVED = $4fff;
  120.   DDE_FPOKRESERVED = $dfff;
  121.  
  122.   { message filter hook types }
  123.  
  124.   MSGF_DDEMGR = $8001;
  125.  
  126.   { default codepage for windows & old DDE convs. }
  127.  
  128.   CP_WINANSI = 1004;
  129.   CP_WINUNICODE = 1200;
  130.  
  131.     {$IFDEF UNICODE}
  132.     CP_WINNEUTRAL = CP_WINUNICODE;
  133.     {$ELSE}
  134.     CP_WINNEUTRAL = CP_WINANSI;
  135.     {$ENDIF}
  136.   { transaction types }
  137.  
  138.   XTYPF_NOBLOCK = $0002; { CBR_BLOCK will not work }
  139.   XTYPF_NODATA = $0004;  { DDE_FDEFERUPD }
  140.   XTYPF_ACKREQ = $0008;  { DDE_FACKREQ }
  141.  
  142.   XCLASS_MASK = $FC00;
  143.   XCLASS_BOOL = $1000;
  144.   XCLASS_DATA = $2000;
  145.   XCLASS_FLAGS = $4000;
  146.   XCLASS_NOTIFICATION = $8000;
  147.  
  148.   XTYP_ERROR = $0000 or XCLASS_NOTIFICATION or XTYPF_NOBLOCK;
  149.   XTYP_ADVDATA = $0010 or XCLASS_FLAGS;
  150.   XTYP_ADVREQ = $0020 or XCLASS_DATA or XTYPF_NOBLOCK;
  151.   XTYP_ADVSTART = $0030 or XCLASS_BOOL;
  152.   XTYP_ADVSTOP = $0040 or XCLASS_NOTIFICATION;
  153.   XTYP_EXECUTE = $0050 or XCLASS_FLAGS;
  154.   XTYP_CONNECT = $0060 or XCLASS_BOOL or XTYPF_NOBLOCK;
  155.   XTYP_CONNECT_CONFIRM = $0070 or XCLASS_NOTIFICATION or XTYPF_NOBLOCK;
  156.   XTYP_XACT_COMPLETE = $0080 or XCLASS_NOTIFICATION;
  157.   XTYP_POKE = $0090 or XCLASS_FLAGS;
  158.   XTYP_REGISTER = $00A0 or XCLASS_NOTIFICATION or XTYPF_NOBLOCK;
  159.   XTYP_REQUEST = $00B0 or XCLASS_DATA;
  160.   XTYP_DISCONNECT = $00C0 or XCLASS_NOTIFICATION or XTYPF_NOBLOCK;
  161.   XTYP_UNREGISTER = $00D0 or XCLASS_NOTIFICATION or XTYPF_NOBLOCK;
  162.   XTYP_WILDCONNECT = $00E0 or XCLASS_DATA or XTYPF_NOBLOCK;
  163.  
  164.   XTYP_MASK = $00F0;
  165.   XTYP_SHIFT = 4;  { shift to turn xtyp_ into an index }
  166.  
  167.   { Timeout constants }
  168.  
  169.   TIMEOUT_ASYNC =           -1;
  170.  
  171.   { Transaction ID constatnts }
  172.   QID_SYNC =                -1;
  173.  
  174.   { public strings used in DDE }
  175.  
  176.   SZDDESYS_TOPIC = 'System';
  177.   SZDDESYS_ITEM_TOPICS = 'Topics';
  178.   SZDDESYS_ITEM_SYSITEMS = 'SysItems';
  179.   SZDDESYS_ITEM_RTNMSG = 'ReturnMessage';
  180.   SZDDESYS_ITEM_STATUS = 'Status';
  181.   SZDDESYS_ITEM_FORMATS = 'Formats';
  182.   SZDDESYS_ITEM_HELP = 'Help';
  183.   SZDDE_ITEM_ITEMLIST = 'TopicItemList';
  184.  
  185. type
  186.   { API entry points }
  187.   TFNCallback = function (CallType, Fmt: UINT; Conv: HConv; hsz1, hsz2: HSZ;
  188.     Data: HDDEData; Data1, Data2: DWORD): HDDEData stdcall;
  189.  
  190. const
  191.   CBR_BLOCK = $FFFFFFFF;
  192.  
  193. { DLL registration functions }
  194.  
  195. function DdeInitializeA(var Inst: Longint; Callback: TFNCallback;
  196.   Cmd, Res: Longint): Longint; stdcall;
  197. function DdeInitializeW(var Inst: Longint; Callback: TFNCallback;
  198.   Cmd, Res: Longint): Longint; stdcall;
  199. function DdeInitialize(var Inst: Longint; Callback: TFNCallback;
  200.   Cmd, Res: Longint): Longint; stdcall;
  201.  
  202. const
  203.   { Callback filter flags for use with standard apps. }
  204.  
  205.   CBF_FAIL_SELFCONNECTIONS = $00001000;
  206.   CBF_FAIL_CONNECTIONS = $00002000;
  207.   CBF_FAIL_ADVISES = $00004000;
  208.   CBF_FAIL_EXECUTES = $00008000;
  209.   CBF_FAIL_POKES = $00010000;
  210.   CBF_FAIL_REQUESTS = $00020000;
  211.   CBF_FAIL_ALLSVRXACTIONS = $0003f000;
  212.  
  213.   CBF_SKIP_CONNECT_CONFIRMS = $00040000;
  214.   CBF_SKIP_REGISTRATIONS = $00080000;
  215.   CBF_SKIP_UNREGISTRATIONS = $00100000;
  216.   CBF_SKIP_DISCONNECTS = $00200000;
  217.   CBF_SKIP_ALLNOTIFICATIONS = $003c0000;
  218.  
  219.   { Application command flags }
  220.  
  221.   APPCMD_CLIENTONLY = $00000010;
  222.   APPCMD_FILTERINITS = $00000020;
  223.   APPCMD_MASK = $00000FF0;
  224.  
  225.   { Application classification flags }
  226.  
  227.   APPCLASS_STANDARD = $00000000;
  228.   APPCLASS_MASK = $0000000F;
  229.  
  230. function DdeUninitialize(Inst: DWORD): BOOL; stdcall;
  231.  
  232. { conversation enumeration functions }
  233.  
  234. function DdeConnectList(Inst: DWORD; Service, Topic: HSZ;
  235.   ConvList: HConvList; CC: PConvContext): HConvList; stdcall;
  236. function DdeQueryNextServer(ConvList: HConvList; ConvPrev: HConv): HConv; stdcall;
  237. function DdeDisconnectList(ConvList: HConvList): BOOL; stdcall;
  238.  
  239. { conversation control functions }
  240.  
  241. function DdeConnect(Inst: DWORD; Service, Topic: HSZ;
  242.   CC: PConvContext): HConv; stdcall;
  243. function DdeDisconnect(Conv: HConv): BOOL; stdcall;
  244. function DdeReconnect(Conv: HConv): HConv; stdcall;
  245.  
  246. function DdeQueryConvInfo(Conv: HConv; Transaction: DWORD;
  247.  ConvInfo: PConvInfo): UINT; stdcall;
  248. function DdeSetUserHandle(Conv: HConv; ID, User: DWORD): BOOL; stdcall;
  249.  
  250. function DdeAbandonTransaction(Inst: DWORD; Conv: HConv;
  251.   Transaction: DWORD): BOOL; stdcall;
  252.  
  253. { app server interface functions }
  254.  
  255. function DdePostAdvise(Inst: DWORD; Topic, Item: HSZ): BOOL; stdcall;
  256. function DdeEnableCallback(Inst: DWORD; Conv: HConv; Cmd: UINT): BOOL; stdcall;
  257.  
  258. const
  259.   EC_ENABLEALL = 0;
  260.   EC_ENABLEONE = ST_BLOCKNEXT;
  261.   EC_DISABLE = ST_BLOCKED;
  262.   EC_QUERYWAITING = 2;
  263.  
  264. function DdeNameService(Inst: DWORD; hsz1, hsz2: HSZ; Cmd: UINT): HDDEData; stdcall;
  265.  
  266. const
  267.   DNS_REGISTER = $0001;
  268.   DNS_UNREGISTER = $0002;
  269.   DNS_FILTERON = $0004;
  270.   DNS_FILTEROFF = $0008;
  271.  
  272. { app client interface functions }
  273.  
  274. function DdeClientTransaction(Data: Pointer; DataLen: DWORD;
  275.   Conv: HConv; Item: HSZ; Fmt, DataType: UINT; Timeout: DWORD;
  276.   Result: PDWORD): HDDEData; stdcall;
  277.  
  278. { data transfer functions }
  279.  
  280. function DdeCreateDataHandle(Inst: DWORD; Src: Pointer;
  281.   cb, Off: DWORD; Item: HSZ; Fmt, Cmd: UINT): HDDEData; stdcall;
  282.  
  283. function DdeAddData(Data: HDDEData; Src: Pointer;
  284.   cb, Off: DWORD): HDDEData; stdcall;
  285. function DdeGetData(Data: HDDEData; Dst: Pointer;
  286.   Max, Off: DWORD): DWORD; stdcall;
  287. function DdeAccessData(Data: HDDEData; DataSize: PDWORD): Pointer; stdcall;
  288. function DdeUnaccessData(Data: HDDEData): BOOL; stdcall;
  289. function DdeFreeDataHandle(Data: HDDEData): BOOL; stdcall;
  290.  
  291. const
  292.   HDATA_APPOWNED = $0001;
  293.  
  294. function DdeGetLastError(Inst: DWORD): UINT; stdcall;
  295.  
  296. const
  297.   { error codes }
  298.  
  299.   DMLERR_NO_ERROR = 0;       { must be 0 }
  300.  
  301.   DMLERR_FIRST = $4000;
  302.  
  303.   DMLERR_ADVACKTIMEOUT = $4000;
  304.   DMLERR_BUSY = $4001;
  305.   DMLERR_DATAACKTIMEOUT = $4002;
  306.   DMLERR_DLL_NOT_INITIALIZED = $4003;
  307.   DMLERR_DLL_USAGE = $4004;
  308.   DMLERR_EXECACKTIMEOUT = $4005;
  309.   DMLERR_INVALIDPARAMETER = $4006;
  310.   DMLERR_LOW_MEMORY = $4007;
  311.   DMLERR_MEMORY_ERROR = $4008;
  312.   DMLERR_NOTPROCESSED = $4009;
  313.   DMLERR_NO_CONV_ESTABLISHED = $400a;
  314.   DMLERR_POKEACKTIMEOUT = $400b;
  315.   DMLERR_POSTMSG_FAILED = $400c;
  316.   DMLERR_REENTRANCY = $400D;
  317.   DMLERR_SERVER_DIED = $400E;
  318.   DMLERR_SYS_ERROR = $400F;
  319.   DMLERR_UNADVACKTIMEOUT = $4010;
  320.   DMLERR_UNFOUND_QUEUE_ID = $4011;
  321.  
  322.   DMLERR_LAST = $4011;
  323.  
  324. function DdeCreateStringHandleA(Inst: DWORD; psz: PAnsiChar;
  325.   CodePage: Integer): HSZ; stdcall;
  326. function DdeCreateStringHandleW(Inst: DWORD; psz: PWideChar;
  327.   CodePage: Integer): HSZ; stdcall;
  328. function DdeCreateStringHandle(Inst: DWORD; psz: PChar;
  329.   CodePage: Integer): HSZ; stdcall;
  330. function DdeQueryStringA(Inst: DWORD; HSZ: HSZ; psz: PAnsiChar;
  331.   Max: DWORD; CodePage: Integer): DWORD; stdcall;
  332. function DdeQueryStringW(Inst: DWORD; HSZ: HSZ; psz: PWideChar;
  333.   Max: DWORD; CodePage: Integer): DWORD; stdcall;
  334. function DdeQueryString(Inst: DWORD; HSZ: HSZ; psz: PChar;
  335.   Max: DWORD; CodePage: Integer): DWORD; stdcall;
  336. function DdeFreeStringHandle(Inst: DWORD; HSZ: HSZ): BOOL; stdcall;
  337. function DdeKeepStringHandle(Inst: DWORD; HSZ: HSZ): BOOL; stdcall;
  338. function DdeCmpStringHandles(hsz1, hsz2: HSZ): Integer; stdcall;
  339.  
  340. type
  341.   { DDEML public debugging header file info }
  342.  
  343.   TDdemlMsgHookData = packed record  { new for NT }
  344.     uiLo: UINT;      { unpacked lo and hi parts of lParam }
  345.     uiHi: UINT;
  346.     cbData: DWORD;   { amount of data in message, if any. May be > than 32 bytes. }
  347.     Data: array [0..7] of DWORD; { data peeking by DDESPY is limited to 32 bytes. }
  348.   end;
  349.  
  350.   TMonMsgStruct = packed record
  351.     cb: UINT;
  352.     hWndTo: HWND;
  353.     dwTime: DWORD;
  354.     hTask: THandle;
  355.     wMsg: UINT;
  356.     wParam: WPARAM;
  357.     lParam: LPARAM;
  358.     dmhd: TDdemlMsgHookData;
  359.   end;
  360.  
  361.   TMonCBStruct = packed record
  362.     cb: UINT;
  363.     dwTime: DWORD;
  364.     hTask: THandle;
  365.     dwRet: DWORD;
  366.     wType: UINT;
  367.     wFmt: UINT;
  368.     hConv: HConv;
  369.     hsz1: HSZ;
  370.     hsz2: HSZ;
  371.     hData: HDDEData;
  372.     dwData1: DWORD;
  373.     dwData2: DWORD;
  374.     cc: TConvContext;  { new for NT for XTYP_CONNECT callbacks }
  375.     cbData: DWORD;     { new for NT for data peeking }
  376.     Data: array [0..7] of DWORD; { new for NT for data peeking }
  377.   end;
  378.  
  379.   TMonHSZStructA = record
  380.     cb: UINT;
  381.     fsAction: BOOL;    { mh_ value }
  382.     dwTime: DWORD;
  383.     HSZ: HSZ;
  384.     hTask: THandle;
  385.     wReserved: UINT;
  386.     Str: array[0..0] of AnsiChar;
  387.   end;
  388.   TMonHSZStructW = record
  389.     cb: UINT;
  390.     fsAction: BOOL;    { mh_ value }
  391.     dwTime: DWORD;
  392.     HSZ: HSZ;
  393.     hTask: THandle;
  394.     wReserved: UINT;
  395.     Str: array[0..0] of WideChar;
  396.   end;
  397.   TMonHSZStruct = TMonHSZStructA;
  398.  
  399. const
  400.   MH_CREATE = 1;
  401.   MH_KEEP = 2;
  402.   MH_DELETE = 3;
  403.   MH_CLEANUP = 4;
  404.  
  405. type
  406.   PMonErrStruct = ^TMonErrStruct;
  407.   TMonErrStruct = packed record
  408.     cb: UINT;
  409.     wLastError: UINT;
  410.     dwTime: DWORD;
  411.     hTask: THandle;
  412.   end;
  413.  
  414.   PMonLinkStruct = ^TMonLinkStruct;
  415.   TMonLinkStruct = packed record
  416.     cb: UINT;
  417.     dwTime: DWORD;
  418.     hTask: THandle;
  419.     fEstablished: BOOL;
  420.     fNoData: BOOL;
  421.     hszSvc: HSz;
  422.     hszTopic: HSz;
  423.     hszItem: HSz;
  424.     wFmt: UINT;
  425.     fServer: BOOL;
  426.     hConvServer: HConv;
  427.     hConvClient: HConv;
  428.   end;
  429.  
  430.   PMonConvStruct = ^TMonConvStruct;
  431.   TMonConvStruct = packed record
  432.     cb: UINT;
  433.     fConnect: BOOL;
  434.     dwTime: DWORD;
  435.     hTask: THandle;
  436.     hszSvc: HSz;
  437.     hszTopic: HSz;
  438.     hConvClient: HConv;
  439.     hConvServer: HConv;
  440.   end;
  441.  
  442. const
  443.   MAX_MONITORS = 4;
  444.   APPCLASS_MONITOR = 1;
  445.   XTYP_MONITOR = $00F0 or XCLASS_NOTIFICATION or XTYPF_NOBLOCK;
  446.  
  447. { Callback filter flags for use with MONITOR apps - 0 implies no monitor
  448.   callbacks. }
  449.  
  450. const
  451.   MF_HSZ_INFO = $01000000;
  452.   MF_SENDMSGS = $02000000;
  453.   MF_POSTMSGS = $04000000;
  454.   MF_CALLBACKS = $08000000;
  455.   MF_ERRORS = $10000000;
  456.   MF_LINKS = $20000000;
  457.   MF_CONV = $40000000;
  458.  
  459.  
  460.   ddelib = 'user32.dll';
  461.  
  462. implementation
  463.  
  464. function DdeInitializeA;         external ddelib name 'DdeInitializeA';
  465. function DdeInitializeW;         external ddelib name 'DdeInitializeW';
  466. function DdeInitialize;         external ddelib name 'DdeInitializeA';
  467. function DdeUninitialize;          external ddelib name 'DdeUninitialize';
  468. function DdeConnectList;           external ddelib name 'DdeConnectList';
  469. function DdeQueryNextServer;       external ddelib name 'DdeQueryNextServer';
  470. function DdeDisconnectList;        external ddelib name 'DdeDisconnectList';
  471. function DdeConnect;               external ddelib name 'DdeConnect';
  472. function DdeDisconnect;            external ddelib name 'DdeDisconnect';
  473. function DdeReconnect;             external ddelib name 'DdeReconnect';
  474. function DdeQueryConvInfo;         external ddelib name 'DdeQueryConvInfo';
  475. function DdeSetUserHandle;         external ddelib name 'DdeSetUserHandle';
  476. function DdeAbandonTransaction;    external ddelib name 'DdeAbandonTransaction';
  477. function DdePostAdvise;            external ddelib name 'DdePostAdvise';
  478. function DdeEnableCallback;        external ddelib name 'DdeEnableCallback';
  479. function DdeNameService;           external ddelib name 'DdeNameService';
  480. function DdeClientTransaction;     external ddelib name 'DdeClientTransaction';
  481. function DdeCreateDataHandle;      external ddelib name 'DdeCreateDataHandle';
  482. function DdeAddData;               external ddelib name 'DdeAddData';
  483. function DdeGetData;               external ddelib name 'DdeGetData';
  484. function DdeAccessData;            external ddelib name 'DdeAccessData';
  485. function DdeUnaccessData;          external ddelib name 'DdeUnaccessData';
  486. function DdeFreeDataHandle;        external ddelib name 'DdeFreeDataHandle';
  487. function DdeGetLastError;          external ddelib name 'DdeGetLastError';
  488. function DdeCreateStringHandleA; external ddelib name 'DdeCreateStringHandleA';
  489. function DdeCreateStringHandleW; external ddelib name 'DdeCreateStringHandleW';
  490. function DdeCreateStringHandle; external ddelib name 'DdeCreateStringHandleA';
  491. function DdeQueryStringA;        external ddelib name 'DdeQueryStringA';
  492. function DdeQueryStringW;        external ddelib name 'DdeQueryStringW';
  493. function DdeQueryString;        external ddelib name 'DdeQueryStringA';
  494. function DdeFreeStringHandle;      external ddelib name 'DdeFreeStringHandle';
  495. function DdeKeepStringHandle;      external ddelib name 'DdeKeepStringHandle';
  496. function DdeCmpStringHandles;      external ddelib name 'DdeCmpStringHandles';
  497.  
  498. end.
  499.